---
title: Provider生命周期
---

import CodeBlock from "@theme/CodeBlock";
import onDispose from "./lifecycle_on_dispose";
import { trimSnippet, CodeSnippet, AutoSnippet } from "../../../../../src/components/CodeSnippet";

## 什么时候创建并销毁我的Provider？

所有不同类型的provider经历的状态是相同的：

- 未初始化
- 活动中
- 暂停
- 已销毁

### 已销毁 / 未初始化

**未初始化**或**已销毁**的provider不占用任何内存，因为它的状态没有初始化。
从本质上来说，它只是定义了在你需要时如何创建provider的状态。
它将一直保持这种状态，直到**活动中**provider被创建或由于UI中的[WidgetRef] 读取、观察或监听它。

### 创建中 -> 活动中

当读取、监听或观察**未初始化**的provider时，将创建其状态。

在创建期间，你的provider的构建函数将会运行。
使用回调函数所暴露的 `ref` 读取(read)或观察(watch)的任何provider将根据需要创建，并且将检索它们的状态。

如果在创建过程中存在任何循环依赖关系，Riverpod将抛出一个错误。
修复此错误的最佳方式是重新设计依赖项，使其具有单向数据流。

provider的状态存储在 [ProviderContainer] 中。在Flutter应用中，此容器位于[ProviderScope] widget中。

因此，尽管如何创建状态(provider)的定义是全局的，但状态实际上是本地的，
并且使用嵌套的[ProviderScope] widget和覆盖在UI的不同部分中有所不同。

这与flutter widget的工作方式非常相似。你只需为其定义一次，
但是可以根据需要在树的不同部分重用状态。

### 活动中

当你的provider为**活动中**时，对其状态的更改将导致依赖的provider和/或依赖的UI重新构建。

从另一个角度来看，作为响应式框架，你可以观察其他provider，以便在它的某个依赖项发生变化时重建自己。

如果你需要一些依赖于其他状态的长期状态，你可以使用Ref的 [listen] 方法来订阅另一个provider上的更改，而不会导致重新构建该provider。

如果你需要使用来自另一个可能有副作用的provider的状态，你可以使用Ref的[read]方法从另一个provider获取当前状态。

通常，在构造 [StateNotifier] 或 [ChangeNotifier] 类时，应该传入引用，
以允许Notifier根据需要获取依赖项的当前值。
通过使用来自Riverpod 2.0的新[Notifier] 和 [AsyncNotifier]类，ref已经作为类的实例成员可用。

### 活动中 -> 暂停
当其他provider或UI不再监听**活动的** provider时，它将进入**暂停**状态。这意味着它将不再对正在监听的provider的更改做出反应。
这是一种优化，如果你没有监听的provider，就没有必要让它保持活动状态。每个未被使用的provider都将返回到**暂停**状态，从而减少你的应用的计算负担。

如果你需要让provider保持活动状态以防止副作用发生，请确保在UI中应该保持活动状态的适当位置监听它。

如果你需要在provider暂停时执行一些操作，请使用ref的 [onCancel] 方法来注册回调函数。

当provider从暂停状态恢复到活动状态时，如果你需要执行一些操作，请使用ref的[onResume]方法来注册回调。

如果你想销毁状态，那么除了不占用计算资源外，还可以销毁状态的内存，请在provider上使用`.autoDispose`修饰符。
这将导致它在不再被使用时转换到**已销毁**状态，而不是**暂停**状态。

### 活动中 -> 销毁中

销毁provider有几个原因。

- 当使用`.autoDispose`修饰符定义并不再被UI或其他providerg观察时
- 当手动刷新或provider失效时
- 当provider由于被监视的依赖项之一发生变化而被重新创建时

刷新会导致provider立即再次执行创建过程，而无效则会导致provider的下一次读取/观察导致重新构建provider。

## 在状态被销毁前执行操作
如果你需要在销毁provider时执行一些操作，使用ref的 [onDispose] 方法来注册回调函数。

下面的例子使用onDispose关闭StreamController：

<AutoSnippet {...onDispose}></AutoSnippet>

:::note
根据所使用的provider，它可能已经处理了清理过程。
例如，[StateNotifierProvider] 将调用返回的 [StateNotifier] 的`dispose`方法。
:::

[onDispose]: https://pub.dev/documentation/riverpod/latest/riverpod/Ref/onDispose.html
[listen]: https://pub.dev/documentation/riverpod/latest/riverpod/Ref/listen.html
[onCancel]: https://pub.dev/documentation/riverpod/latest/riverpod/Ref/onCancel.html
[onResume]: https://pub.dev/documentation/riverpod/latest/riverpod/Ref/onResume.html
[ProviderContainer]: https://pub.dev/documentation/riverpod/latest/riverpod/ProviderContainer-class.html
[Notifier]: https://pub.dev/documentation/riverpod/latest/riverpod/Notifier-class.html
[AsyncNotifier]: https://pub.dev/documentation/riverpod/latest/riverpod/AsyncNotifier-class.html
[ProviderScope]: https://pub.dev/documentation/flutter_riverpod/latest/flutter_riverpod/ProviderScope-class.html
[WidgetRef]: https://pub.dev/documentation/flutter_riverpod/latest/flutter_riverpod/WidgetRef-class.html
[StateNotifier]: https://pub.dev/documentation/state_notifier/latest/state_notifier/StateNotifier-class.html
[StateNotifierProvider]: https://pub.dev/documentation/riverpod/latest/riverpod/StateNotifierProvider-class.html
[StreamController]: https://api.dart.dev/stable/2.15.1/dart-async/StreamController-class.html
[ChangeNotifier]: https://api.flutter.dev/flutter/foundation/ChangeNotifier-class.html
